﻿using Microsoft.AspNetCore.Http;
using System.Text;

namespace RemoteSensingImageDirectServer.Register.Http
{
    public class InternetProxyMiddleware : IInternetProxy
    {
        /// <summary>
        /// 配置注入
        /// </summary>
        private readonly IConfiguration _configuration;

        /// <summary>
        /// 网络请求注入
        /// </summary>
        private readonly IHttpContextAccessor _httpContextAccessor;

        /// <summary>
        /// 是否使用动态ip
        /// </summary>
        private readonly bool _useRequestHeader;

        /// <summary>
        /// 本地配置的ip
        /// </summary>
        private readonly string _ip;

        /// <summary>
        /// 本地配置的端口
        /// </summary>
        private readonly int _port;

        private const string ip_attr = "x-proxy-version";
        private const string ip_v1_host = "host";
        private const string ip_v1_port = "port";
        private const string ip_v2_host = "x-req-hostname";
        private const string ip_v2_port = "x-req-port";


        public InternetProxyMiddleware(IConfiguration configuration, IHttpContextAccessor httpContextAccessor)
        {
            this._configuration = configuration;
            this._httpContextAccessor = httpContextAccessor;
            this._useRequestHeader = _configuration.GetValue<bool>("InternetConfig:UseRequestHeader");
            this._ip = _configuration.GetValue<string>("InternetConfig:IP");
            this._port = _configuration.GetValue<int>("InternetConfig:PORT");
        }

        public string GetIP()
        {
            try
            {
                if (!this._useRequestHeader) return _ip;

                var request = _httpContextAccessor.HttpContext?.Request;

                if (request == null) return _ip;

                var reqList = request?.Headers.ToList();

                var ip_version = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_attr));
                if (ip_version.Value.ToString().ToLower().Equals("v1"))
                {
                    var ip_host = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_v1_host));
                    return ip_host.Value.ToString();
                }
                else if (ip_version.Value.ToString().ToLower().Equals("v2"))
                {
                    var ip_host = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_v2_host));
                    return ip_host.Value.ToString();
                }
                else
                {
                    var ip_host = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_v1_host));
                    return ip_host.Value.ToString();
                }
            }
            catch (Exception ms)
            {
                return null;
            }
        }

        public string GetPort()
        {
            try
            {
                if (!this._useRequestHeader) return _port.ToString();

                var request = _httpContextAccessor.HttpContext?.Request;

                if (request == null) return _ip;

                var reqList = request.Headers.ToList();
                var ip_version = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_attr));
                if (ip_version.Value.ToString().ToLower().Equals("v1"))
                {
                    var ip_port = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_v1_port));
                    return ip_port.Value.ToString();
                }
                else if (ip_version.Value.ToString().ToLower().Equals("v2"))
                {
                    var ip_port = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_v2_port));
                    return ip_port.Value.ToString();
                }
                else
                {
                    var ip_port = reqList.SingleOrDefault(q => q.Key.ToLower().Contains(ip_v1_port));
                    return ip_port.Value.ToString();
                }
            }
            catch
            {
                return "";
            }
        }

        public string? GetCurrentScheme()
        {
            try
            {
                var httpContext = _httpContextAccessor.HttpContext;

                return httpContext?.Request.Scheme;
            }
            catch
            {
                return "";
            }
        }

        public string? GetCurrentPath()
        {
            try
            {
                var httpContext = _httpContextAccessor.HttpContext;

                return httpContext?.Request.Path;
            }
            catch
            {
                return "";
            }
        }

        public string? GetCurrentUri()
        {
            var Request_URL = new StringBuilder()
                  .Append(GetCurrentScheme())
                  .Append("://")
                  .Append(GetIP())
                  .Append(':')
                  .Append(GetPort())
                  .Append(GetCurrentPath())
                  .Append('?')
                  .ToString();

            return Request_URL.ToString();
        }
    }
}
